<template>
    <el-select class="search-select-tree"
        ref="select"
        v-model="selectFormatValue"
        filterable
        :multiple="multiple"
        :collapse-tags="multiple"
        @change="changeSelectValue"
        @visible-change="visibleChange(option, index, $event)">
        <template #empty>
            <div class="tree-empty">
                <el-input class="tree-filter-input"
                    v-model="treeFilterText"
                    size="mini"
                    clearable
                    suffix-icon="el-icon-search"
                    placeholder="输入关键字进行过滤"
                    @input="search">
                </el-input>
                <el-tree class="select-tree"
                    ref="tree"
                    :data="option.options"
                    :expand-on-click-node="false"
                    :props="option.optionTreeProps"
                    :node-key="option.nodeKey"
                    :highlight-current="!multiple"
                    :show-checkbox="multiple"
                    check-strictly
                    :default-expanded-keys="defaultExpandedKeys"
                    :filter-node-method="filterNode"
                    @node-click="handleClickTree"
                    @check="handleClickTreeCheckbox"
                >
                </el-tree>
            </div>
        </template>
    </el-select>
</template>

<script>
import normalMixin from "../mixin/normalMixin";
export default {
    name: "searchSelectTree",
    mixins: [normalMixin],
    data() {
        return {
            selectFormatValue: "",
            treeFilterText: "", // tree 检索
            treeDataMap: {} // 存储选择的数据 id => value
        }
    },
    methods: {
        handleClickTree(data) {
            if (this.multiple) { // 多选
                // 存储选择的值
                this.treeDataMap[data[this.option.nodeKey]] = data;
                const checkedKeys = this.$refs.tree.getCheckedKeys();
                const newCheckedKeys = checkedKeys.includes(data[this.option.nodeKey]) ? checkedKeys.filter(id => id !== data[this.option.nodeKey]) : checkedKeys.concat([data[this.option.nodeKey]]);
                // 点击tree-node 复选框true状态
                this.$refs.tree.setCheckedKeys(newCheckedKeys);
                // 属性赋值
                this.option.value = newCheckedKeys;
                this.selectFormatValue = newCheckedKeys.map(id => this.treeDataMap[id]?.[this.option.optionTreeProps?.['label'] || 'label']);
                this.option.selectFormatValue = this.selectFormatValue.toString();
                // change 事件
                this.changeSelectSearchItem(this.$refs.tree.getCheckedNodes());
            } else { // 单选
                this.option.value = data[this.option.nodeKey];
                this.selectFormatValue = data[this.option.optionTreeProps?.['label'] || 'label'];
                this.option.selectFormatValue = this.selectFormatValue;
                this.$refs.select.blur();
                // change 事件
                this.changeSelectSearchItem(data);
            }
        },
        /**
         * change 事件处理
         * 多选模式下选择tree的复选框触发
         */
        handleClickTreeCheckbox(data, { checkedKeys }) {
            this.treeDataMap[data[this.option.nodeKey]] = data;
            this.option.value = checkedKeys;
            this.selectFormatValue = checkedKeys.map(id => this.treeDataMap[id]?.[this.option.optionTreeProps?.['label'] || 'label']);
            this.option.selectFormatValue = this.selectFormatValue.toString();
            // change 事件
            this.changeSelectSearchItem(this.$refs.tree.getCheckedNodes());
        },
        search(val) { // tree input 事件
            this.$refs.tree.filter(val);
        },
        filterNode(value, data) { // tree 数据检索
            if (!value) return true;
            return data[this.option.optionTreeProps?.['label'] || 'label'].indexOf(value) !== -1;
        },
        visibleChange(option, index, $event) { // 单选回显高亮/多选框回显
            this.blurSearchItem(option, index, $event);
            if ($event) {
                this.$nextTick(() => {
                    if (option.multiple) { // 多选
                        // 复选框回显
                        this.$refs.tree.setCheckedKeys(option.value || []);
                        // input tags回显
                        let selectNodes = this.$refs.tree.getCheckedNodes();
                        selectNodes.forEach(item => {
                            this.treeDataMap[item[this.option.nodeKey]] = item;
                        })
                        this.selectFormatValue = option.value.map(id => this.treeDataMap[id]?.[this.option.optionTreeProps?.['label'] || 'label']);
                        this.option.selectFormatValue = this.selectFormatValue.toString();
                    } else { // 单选
                        this.$refs.tree.setCurrentKey(this.option.value || null);
                        this.selectFormatValue = this.option.selectFormatValue;
                    }
                })
            }
        },
        /**
         * select change 事件
         * 点击关闭 tags标签时触发
         */
        changeSelectValue(value) {
            if (Array.isArray(value)) {
                const deptInfoList = this.option.value.map(id => this.treeDataMap[id]);
                this.option.value = deptInfoList.filter(v => value.includes(v[this.option.optionTreeProps?.['label'] || 'label'])).map(v => v[this.option.nodeKey]);
                this.selectFormatValue = this.option.value.map(id => this.treeDataMap[id]?.[this.option.optionTreeProps?.['label'] || 'label']);
                this.option.selectFormatValue = this.selectFormatValue.toString();
                this.$refs.tree && this.$refs.tree.setCheckedKeys(this.option.value || []);
                // change 事件
                this.changeSelectSearchItem(this.$refs.tree.getCheckedNodes());
            }
        },
        /**
         * SelectTree 组件change事件触发的事件
         * @param {Array|Object} data select返回数据组件
         */
        changeSelectSearchItem(data) {
            if (this.option.changeMethod) this.option.changeMethod(data);
        }
    },
    computed: {
        defaultExpandedKeys() { // 默认展开节点
            return this.option?.defaultExpandedKeys || [];
        },
        multiple() { // 多选
            return this.option.multiple
        }
    }
}
</script>

<style>
    .select-tree.el-tree {
        max-height: 300px;
    }
    .select-tree.el-tree .el-tree-node__content {
        height: 30px;
    }
    .tree-empty {
        padding: 10px 5px;
    }
    .tree-empty .tree-filter-input {
        margin-bottom: 5px;
    }
</style>